home *** CD-ROM | disk | FTP | other *** search
- // TSMorph - Amiga Morphing program
- // Copyright (C) © 1993 Topicsave Limited
-
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2 of the License, or
- // any later version.
-
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
-
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- // mpaddock@cix.compulink.co.uk
-
- // include headers if not precompiled
- #ifndef TSMORPH_H
- #include "TSMorph.h"
- #endif
-
- LONG OldFrame; // Previous frame number
-
- /* Go to the first frame
- * the return value is that used by the main message loop
- */
- int
- FirstFrame(void) {
- OldFrame=FrameNumber; // Store old frame
- FrameNumber = GetNumber(TSMorphGadgets[GDX_Start]); // get starting frame
- if (FrameNumber != OldFrame) { // if different
- return ReopenPictures(); // try and move to new frame
- }
- return 1;
- }
-
- /* Go to the previous frame
- * See FirstFrame()
- */
- int
- PrevFrame(void) {
- OldFrame=FrameNumber;
- if (FrameNumber > GetNumber(TSMorphGadgets[GDX_Start])) {
- --FrameNumber; // previous frame
- return ReopenPictures();
- }
- return 1;
- }
-
- /* Go to the previous frame
- * See FirstFrame()
- */
- int
- GotoFrame(void) {
- OldFrame=FrameNumber;
- GetFrameNumber(); // Request frame number
- if (FrameNumber != OldFrame) {
- return ReopenPictures();
- }
- return 1;
- }
-
- /* Go to the next frame
- * See FirstFrame()
- */
- int
- NextFrame(void) {
- OldFrame=FrameNumber; // next determine last frame number
- if (FrameNumber < (GetNumber(TSMorphGadgets[GDX_Start]) + GetNumber(TSMorphGadgets[GDX_Frames]) -1)) {
- ++FrameNumber;
- return ReopenPictures();
- }
- return 1;
- }
-
- /* Go to the last frame
- * See NextFrame()
- */
- int
- LastFrame(void) {
- OldFrame=FrameNumber;
- FrameNumber = GetNumber(TSMorphGadgets[GDX_Start]) + GetNumber(TSMorphGadgets[GDX_Frames]) - 1;
- if (FrameNumber != OldFrame) {
- return ReopenPictures();
- }
- return 1;
- }
-
- /* Request frame number
- * returns TRUE if not cancelled
- * selected frame is stored in FrameNumber
- * This could use a nice sliding gadet requester - actually uses reqtools
- */
- BOOL
- GetFrameNumber(void) {
- LONG Frames, Start; // Number of frames and starting frame
- ULONG ret = 2; // loop flag
- struct AmigaGuideMsg *agm; // for help
- ULONG signals; // signals to wait on
- struct rtHandlerInfo *rth; // reqtools stuff
-
- Frames = GetNumber(TSMorphGadgets[GDX_Frames]); // Get frames and start frame
- Start = GetNumber(TSMorphGadgets[GDX_Start]);
- if (Frames > 1) { // No point displaying requester if 0 or 1 frame
- // Determine Current frame number in correct range, using previously held value
- FrameNumber = max(Start,FrameNumber);
- FrameNumber = min(Start+Frames-1,FrameNumber);
- DisableWindows(DI_GetFrame); // Disable all other windows
- while (ret == 2) { // loop until Ok or Cancel (keep looping on Help)
- // if no amigaguide then 2 will never be returned
- ret = CALL_HANDLER; // reqtools stuff
- if (rtGetLong((ULONG *)&FrameNumber,MyGetMsg(MSG_FRAMENO),NULL,
- RT_ReqHandler, &rth,
- RT_Window, TSMorphWnd, // same screen
- RTGL_Min, Start,
- RTGL_Max, Start+Frames-1,
- RTGL_ShowDefault, TRUE,
- RT_Underscore, '_',
- RTGL_GadFmt, handle?MyGetMsg(MSG_OKHC):MyGetMsg(MSG_OKC), // if amigaguide then help gadget
- TAG_END) == CALL_HANDLER) { // Opened requester
- while (ret == CALL_HANDLER) { // Loop well no gadget selected
- if (!rth->DoNotWait) { // Wait if poss.
- signals = Wait(rth->WaitMask | ASig);
- }
- ret = rtReqHandlerA(rth,signals,NULL); // get gadget etc.
- if (ret == 2) { // help gadget
- help(H_FrameNumber);
- }
- if (signals & ASig) { // amigaguide message
- while (agm = GetAmigaGuideMsg(handle)) {
- ReplyAmigaGuideMsg(agm);
- }
- }
- }
- }
- else { // otherwise error so default Cancel
- ret = FALSE;
- }
- }
- EnableWindows(); // enable all the windows
- }
- else {
- if (!Frames) { // number of frames = 0 so error
- Error(MyGetMsg(MSG_MUST1F),MyGetMsg(MSG_OK),NULL,HE_OneFrame);
- ret = FALSE;
- }
- else { // number of frames = 1 so only one choice
- FrameNumber = Start;
- ret = TRUE;
- }
- }
- return (BOOL)ret; // Cancel gadget is 0
- }
-
- /* Closes and reopens images using new frame (in FrameNumber)
- * the return value is that used by the main message loop
- */
- int
- ReopenPictures(void) {
- char buffer[257]; // Work buffer for points file name
- LONG KeepFrame; // Temporary frame number
- if (!Saved) { // if not saved then reset frame number and suggest user saves
- KeepFrame = FrameNumber;
- FrameNumber = OldFrame;
- if (!SaveRequester()) {
- return 1; // user cancelled
- }
- FrameNumber = KeepFrame; // either saved or abandoned so go to new frame
- }
- // Disable the windows and delete all the points
- DisableWindows(DI_NextFrame);
- DeleteAllPoints();
- // Try and reopen image one and two
- if (ReopenAPicture(GetString(TSMorphGadgets[GDX_FileOne]),&Pic1)) {
- if (ReopenAPicture(GetString(TSMorphGadgets[GDX_FileTwo]),&Pic2)) {
- // if ok then set up points filename and try and open
- strcpy(TempFilename,savedfilename);
- strcat(TempFilename,".%03ld");
- sprintf(buffer,TempFilename,FrameNumber);
- MyOpen(buffer,TRUE,FALSE); // Note! do not complain if no points file for thisframe (yet)
- // enable the windows
- EnableWindows();
- // This is nasty!! (and probably unnecessary)
- // but CWTitle is already held as the screen title,
- // so do not want to be writing whilst intuition is reading
- // Probably better to just call SetWindowTitles twice (first time to nothing)
- // But that could cause the screen to flicker?
- Forbid();
- sprintf(CWTitle,MyGetMsg(MSG_TSMFRAME),FrameNumber);
- Permit();
- SetWindowTitles(ControlWindow,(UBYTE *)-1,CWTitle);
- return 1; // It worked
- }
- }
- EnableWindows();
- return 3; // It did not work, so windows are closed, but keep going
- }
-
- /* Opens an image in an (already) open window
- * This is all very convoluted stuff!
- * returns : TRUE or FALSE for sucess failure
- * filename : Name of file
- * pic : pointer to a structure to hold all the stuff
- */
- BOOL
- ReopenAPicture(char *filename,struct Picture *pic) {
- char dirname[257]; // filename storage
- char *e = NULL; // first part of error message
- char *e1 = NULL; // 2nd part of error message
- LONG hnum = 0; // Help number for error
- struct BitMap *OldBitMap = NULL; // BitMap to keep
-
- // Set up new filename and display as screen title
- // window title is done later (does not sound good?)
- sprintf(dirname,filename,FrameNumber);
- Forbid(); // Forbid whilst change window title - Nasty!!
- strcpy(pic->filename,dirname);
- Permit();
- if (EGS) {
- // Unload current frame (keeping bitmap)
- unloadbrush(pic->ilbm);
- // Try and load new brush - if this fails then flag error
- if (!MyLoadBrush(pic,dirname)) {
- e = (char *)-1;
- }
- if (!e) {
- // fail if frame is not the same size as previous
- if ((pic->width != Width) ||
- (pic->height != Height)) {
- e = MyGetMsg(MSG_FRAMESIZE);
- hnum = HE_FAllSize;
- }
- else {
- EI_SetWindowTitles(pic->EGS_Win,FilePart(pic->filename),pic->filename);
- EG_CopyBitMapRastPort(pic->EGS_BitMap,pic->EGS_Win->RPort,0,0,pic->width,pic->height,0,0);
- E_DisposeBitMap(pic->EGS_BitMap);
- pic->EGS_BitMap = NULL;
- }
- }
- else {
- // failed loading new image
- // so close file
- closeifile(&(pic->ilbm->ParseInfo));
- // set up error stuff
- e = MyGetMsg(MSG_FAILLOAD);
- e1 = dirname;
- hnum = HE_LoadImage;
- }
- }
- else {
- SetWindowTitles(pic->Win,(UBYTE *)-1,pic->filename);
- // if we do not allow zoom then the super bitmap is the actual bit map
- // so initialise so we do not lose it when we unload the brush
- if (!ZoomAllowed) {
- // Zero out current bitmap picture
- OldBitMap = pic->ilbm->brbitmap;
- pic->ilbm->brbitmap = NULL;
- }
- // Unload current frame (keeping bitmap)
- unloadbrush(pic->ilbm);
- // Try and load new brush - if this fails then flag error
- if (!MyLoadBrush(pic,dirname)) {
- e = (char *)-1;
- }
- if (!e) {
- // fail if frame is not the same size as previous
- if ((pic->ilbm->Bmhd.w != Width) ||
- (pic->ilbm->Bmhd.h != Height)) {
- // if no zoom allowed then reset the bitmap to the original - freeing the new one
- if (!ZoomAllowed) {
- freebitmap(pic->ilbm);
- pic->ilbm->brbitmap = OldBitMap;
- }
- e = MyGetMsg(MSG_FRAMESIZE);
- hnum = HE_FAllSize;
- }
- else {
- SetWindowTitles(pic->Win,FilePart(pic->filename),pic->filename); // This refreshes the titles
- if (ZoomAllowed) {
- // If we allow zoom then reset up BitScale stuff and scale or copy
- pic->BitScaleArgs.bsa_SrcBitMap = pic->ilbm->brbitmap;
- /* Either scale image 2x or straight copy */
- if (Zoom) {
- BitMapScale(&(pic->BitScaleArgs));
- }
- else {
- BltBitMap(pic->ilbm->brbitmap,0,0,
- &(pic->BitMap),0,0,
- pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
- 0xC0,0xff,NULL);
- }
- }
- else {
- // Zoom is not allowed - so copy the new bit map to the old bit map
- BltBitMap(pic->ilbm->brbitmap,0,0,
- OldBitMap,0,0,
- pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
- 0xC0,0xff,NULL);
- // free the new bit map and set the image back
- freebitmap(pic->ilbm);
- pic->ilbm->brbitmap = OldBitMap;
- // All because we can not change the bitmap of a super bitmap window
- }
- // Resync the display to the new bitmap display
- LockLayerRom(pic->Win->RPort->Layer);
- CopySBitMap(pic->Win->RPort->Layer);
- UnlockLayerRom(pic->Win->RPort->Layer);
- }
- }
- else {
- // failed loading new image
- // so close file
- closeifile(&(pic->ilbm->ParseInfo));
- if (!ZoomAllowed) {
- // if no zoom allowed then free new bit map and restore old
- freebitmap(pic->ilbm);
- pic->ilbm->brbitmap = OldBitMap;
- }
- // set up error stuff
- e = MyGetMsg(MSG_FAILLOAD);
- e1 = dirname;
- hnum = HE_LoadImage;
- }
- }
- // display error (if required) and return status
- if (e) {
- if (e != (char *)-1) { // do not think this is possible?
- Error(e,MyGetMsg(MSG_OK),e1,hnum); // we can actually display two error message
- } // as MyLoadBrush() may have already displayed one
- return FALSE;
- }
- else {
- return TRUE;
- }
- }
-